/*
 * Copyright (C) 2009 Dimitrios C. Michalakos
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.cs.util.dom.transform;

import java.io.File;
import java.io.StringWriter;
import java.net.URISyntaxException;
import java.net.URL;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.w3c.dom.Node;

/**
 *
 * @author dimitris@jmike.gr
 */
public class DocumentTransformer {
    
    private final Transformer transformer;
    private final String mediaType;
    private final String encoding;

    /**
     * Constructs a new DocumentTransformer.
     * @throws TransformerConfigurationException
     */
    public DocumentTransformer() throws TransformerConfigurationException {
        TransformerFactory factory = TransformerFactory.newInstance();
        transformer = factory.newTransformer();
        mediaType = "text/xml";
        encoding = "utf-8";
    }

    /**
     * Constructs a new DocumentTransformer from a XSLT document.
     * @param xslt An XSL transformation document.
     * @throws TransformerConfigurationException
     */
    public DocumentTransformer(Source xslt) throws TransformerConfigurationException {
        TransformerFactory factory = TransformerFactory.newInstance();
        transformer = factory.newTransformer(xslt);
        mediaType = transformer.getOutputProperty("media-type");
        encoding = transformer.getOutputProperty("encoding");
    }

    /**
     * Constructs a new DocumentTransformer from a XSLT document.
     * @param location The location of an XSL transformation document.
     * @throws TransformerConfigurationException
     */
    public DocumentTransformer(String location) throws TransformerConfigurationException {
        Source xslt = new StreamSource(location);
        TransformerFactory factory = TransformerFactory.newInstance();
        transformer = factory.newTransformer(xslt);
        mediaType = transformer.getOutputProperty("media-type");
        encoding = transformer.getOutputProperty("encoding");
    }

    /**
     * Constructs a new DocumentTransformer from a XSLT document.
     * @param url The URL of an XSL transformation document.
     * @throws TransformerConfigurationException
     * @throws java.net.URISyntaxException
     */
    public DocumentTransformer(URL url) throws TransformerConfigurationException, URISyntaxException {
        Source xslt = new StreamSource(new File(url.toURI()));
        TransformerFactory factory = TransformerFactory.newInstance();
        transformer = factory.newTransformer(xslt);
        mediaType = transformer.getOutputProperty("media-type");
        encoding = transformer.getOutputProperty("encoding");
    }


    /**
     * Returns the media-type of the transformation's result.
     * @return
     */
    public String getMediaType() {
        return mediaType;
    }

    /**
     * Returns the character encoding of the transformation's result.
     * @return
     */
    public String getEncoding() {
        return encoding;
    }

    /**
     * Transforms the specified node to String.
     * @param document The document to be transformed.
     * @return A new String transformation.
     * @throws javax.xml.transform.TransformerException
     */
    public String getString(Source document) throws TransformerException {
        StringWriter s = new StringWriter();
        Result result = new StreamResult(s);
        transformer.transform(document, result);
        return s.getBuffer().toString();
    }

    /**
     * Transforms the specified node to String.
     * @param node The node of a document to be transformed.
     * @return A new String transformation.
     * @throws javax.xml.transform.TransformerException
     */
    public String getString(Node node) throws TransformerException {
        StringWriter s = new StringWriter();
        Result result = new StreamResult(s);
        transformer.transform(new DOMSource(node), result);
        return s.getBuffer().toString();
    }
    
}
